/********************************** (C) COPYRIGHT *******************************
 * File Name          : CH394Q.c
 * Author             : WCH
 * Version            : V1.0.1
 * Date               : 2024/12/09
 * Description        : CH394Q application program file
 *******************************************************************************/


#include "ch394q_spi.h"
#include "ch394q.h"
#include "stdio.h"
#include "xgpio.h"
#include "xparameters.h"
#include "sleep.h"
#include "stdio.h"
#include "ch394q_net.h"

extern XGpio   gpio;
#define CH394Q_RESET                         0X0002                //M22
#define CH394Q_RESET_CHANNEL                 1



// #define  QueryCH394QInterrupt() HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_1)
uint8_t MyBuffer[8][128];
uint8_t TX_BUFF[SOCKET_NUM] = {2, 2, 2, 2, 2, 2, 2, 2}; /* Send buffer size    */
uint8_t RX_BUFF[SOCKET_NUM] = {2, 2, 2, 2, 2, 2, 2, 2}; /* Receive buffer size */
/* CH394Q IP Information */
uint8_t CH394Q_MACAddr[6];                     /* CH394Q MAC     */
uint8_t CH394Q_IPAddr[4] = {192, 168, 1, 200}; /* CH394Q IP      */
uint8_t CH394Q_GWIPAddr[4] = {192, 168, 1, 1}; /* CH394Q Gateway */
uint8_t CH394Q_IPMask[4] = {255, 255, 255, 0}; /* CH394Q Mask    */
uint16_t CH394Q_Port = 1000;                   /* CH394Q Port    */
/* Destination IP information */
uint8_t DesIP[4] = {192, 168, 1, 100}; /* Destination IP */
uint16_t DesPort = 1000;               /* Destination port */
/* Multicast IP information */
uint8_t MultiMAC[6] = {0x01, 0x00, 0x5e, 0x01, 0x01, 0x12}; /* Multicast MAC  */
uint8_t MultiIP[4] = {224, 1, 1, 18};                       /* Multicast IP   */
uint16_t MultiPort = 3000;   

/********************************************************************************
 * Function Name  : CH394Q_SetMODE
 * Description    : Set CH394Q mode
 * Input          : mode: Set mode
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetMODE(uint8_t mode)
{
    CH394Q_Write(MODE, mode);
}

/********************************************************************************
 * Function Name  : CH394Q_SetGWIP
 * Description    : Set CH394Q gateway address
 * Input          : gwip: Gateway address
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetGWIP(uint8_t *gwip)
{
    CH394Q_Write(GWIP0, gwip[0]);
    CH394Q_Write(GWIP1, gwip[1]);
    CH394Q_Write(GWIP2, gwip[2]);
    CH394Q_Write(GWIP3, gwip[3]);
}

/********************************************************************************
 * Function Name  : CH394Q_SetSMIP
 * Description    : Set CH394Q subnet mask address
 * Input          : smip: Subnet mask address
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetSMIP(uint8_t *smip)
{
    CH394Q_Write(SMIP0, smip[0]);
    CH394Q_Write(SMIP1, smip[1]);
    CH394Q_Write(SMIP2, smip[2]);
    CH394Q_Write(SMIP3, smip[3]);
}

/********************************************************************************
 * Function Name  : CH394Q_SetMAC
 * Description    : Set CH394Q MAC address
 * Input          : mac: MAC address
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetMAC(uint8_t *mac)
{
    CH394Q_Write(MAC0, mac[0]);
    CH394Q_Write(MAC1, mac[1]);
    CH394Q_Write(MAC2, mac[2]);
    CH394Q_Write(MAC3, mac[3]);
    CH394Q_Write(MAC4, mac[4]);
    CH394Q_Write(MAC5, mac[5]);
}

/********************************************************************************
 * Function Name  : CH394Q_SetIP
 * Description    : Set CH394Q source IP address
 * Input          : ip: IP address
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetIP(uint8_t *ip)
{
    CH394Q_Write(IP0, ip[0]);
    CH394Q_Write(IP1, ip[1]);
    CH394Q_Write(IP2, ip[2]);
    CH394Q_Write(IP3, ip[3]);
}

/********************************************************************************
 * Function Name  : CH394Q_SetIIT
 * Description    : Interrupt interval time register
 * Input          : iit: Wait time
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetIIT(uint16_t iit)
{
    CH394Q_Write(IIT0, (uint8_t)((iit & 0xff00) >> 8));
    CH394Q_Write(IIT1, (uint8_t)(iit & 0x00ff));
}

/********************************************************************************
 * Function Name  : CH394Q_SetGINT
 * Description    : Clear global interrupt flag
 * Input          : gint: Global interrupt flag
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetGINT(uint8_t gint)
{
    CH394Q_Write(GINT, gint);
}

/********************************************************************************
 * Function Name  : CH394Q_SetGINTE
 * Description    : Enable global interrupt
 * Input          : ginte: Enable a global interrupt
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetGINTE(uint8_t ginte)
{
    CH394Q_Write(GINTE, ginte);
}

/********************************************************************************
 * Function Name  : CH394Q_SetSINTE
 * Description    : Enable socket interrupt
 * Input          : sinte: Enable a socket interrupt
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetSINTE(uint8_t sinte)
{
    CH394Q_Write(SINTE, sinte);
}

/********************************************************************************
 * Function Name  : CH394Q_SetRTIME
 * Description    : Set TCP retransmission time
 * Input          : rtime: TCP retransmission time, unit time is 100us
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetRTIME(uint16_t rtime)
{
    CH394Q_Write(RTIME0, (uint8_t)((rtime & 0xff00) >> 8));
    CH394Q_Write(RTIME1, (uint8_t)(rtime & 0x00ff));
}

/********************************************************************************
 * Function Name  : CH394Q_SetRCNT
 * Description    : Set TCP retransmission times
 * Input          : rcnt: TCP retransmission times
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetRCNT(uint8_t rcnt)
{
    CH394Q_Write(RCNT, rcnt);
}

/********************************************************************************
 * Function Name  : CH394Q_SetPHY_CFG
 * Description    : Set PHY configuration
 * Input          : phycfg: Configuration Mode
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetPHY_CFG(uint8_t phycfg)
{
    CH394Q_Write(PHY_CFG, phycfg);
    // HAL_Delay(2); // PHY configuration requires time to take effect
    usleep(2000);// PHY configuration requires time to take effect
}

/********************************************************************************
 * Function Name  : CH394Q_SetSn_MODE
 * Description    : Set socket mode
 * Input          : sockindex: socket number
                    mode: Socket mode
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetSn_MODE(uint8_t sockindex, uint8_t mode)
{
    CH394Q_Write(Sn_MODE(sockindex), mode);
}

/********************************************************************************
 * Function Name  : CH394Q_SetSn_CTRL
 * Description    : Set socket control command
 * Input          : sockindex: socket number
                    ctrl: Control command
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetSn_CTRL(uint8_t sockindex, uint8_t ctrl)
{
    CH394Q_Write(Sn_CTRL(sockindex), ctrl);
    uint16_t i = 0;
    while(i < 100) i++;
}

/********************************************************************************
 * Function Name  : CH394Q_SetSn_INT
 * Description    : Clear the interrupt flag of socket n
 * Input          : sockindex: socket number
                    val: Interrupt flag
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetSn_INT(uint8_t sockindex, uint8_t val)
{
    CH394Q_Write(Sn_INT(sockindex), val);
}

/********************************************************************************
 * Function Name  : CH394Q_SetSn_PORT
 * Description    : Set socket source port
 * Input          : sockindex: socket number
                    port: Source port
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetSn_PORT(uint8_t sockindex, uint16_t port)
{
    CH394Q_Write(Sn_PORT0(sockindex), (uint8_t)((port & 0xff00) >> 8));
    CH394Q_Write(Sn_PORT1(sockindex), (uint8_t)(port & 0x00ff));
}

/********************************************************************************
 * Function Name  : CH394Q_SetSn_DMAC
 * Description    : Set socket destination MAC address
 * Input          : sockindex: socket number
                    dmac: Destination MAC address
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetSn_DMAC(uint8_t sockindex, uint8_t *dmac)
{
    CH394Q_Write(Sn_DMAC0(sockindex), dmac[0]);
    CH394Q_Write(Sn_DMAC1(sockindex), dmac[1]);
    CH394Q_Write(Sn_DMAC2(sockindex), dmac[2]);
    CH394Q_Write(Sn_DMAC3(sockindex), dmac[3]);
    CH394Q_Write(Sn_DMAC4(sockindex), dmac[4]);
    CH394Q_Write(Sn_DMAC5(sockindex), dmac[5]);
}

/********************************************************************************
 * Function Name  : CH394Q_SetSn_DIP
 * Description    : Set socket destination IP address
 * Input          : sockindex: socket number
                    dip: Destination IP address
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetSn_DIP(uint8_t sockindex, uint8_t *dip)
{
    CH394Q_Write(Sn_DIP0(sockindex), dip[0]);
    CH394Q_Write(Sn_DIP1(sockindex), dip[1]);
    CH394Q_Write(Sn_DIP2(sockindex), dip[2]);
    CH394Q_Write(Sn_DIP3(sockindex), dip[3]);
}

/********************************************************************************
 * Function Name  : CH394Q_SetSn_DPORT
 * Description    : Set socket destination port
 * Input          : sockindex: socket number
                    dport: Destination port
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetSn_DPORT(uint8_t sockindex, uint16_t dport)
{
    CH394Q_Write(Sn_DPORT0(sockindex), (uint8_t)((dport & 0xff00) >> 8));
    CH394Q_Write(Sn_DPORT1(sockindex), (uint8_t)(dport & 0x00ff));
}

/********************************************************************************
 * Function Name  : CH394Q_SetSn_MTU
 * Description    : Set socket maximum segmentation register
 * Input          : sockindex: socket number
                    mtu: Maximum segment size
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetSn_MTU(uint8_t sockindex, uint16_t mtu)
{
    CH394Q_Write(Sn_MTU0(sockindex), (uint8_t)((mtu & 0xff00) >> 8));
    CH394Q_Write(Sn_MTU1(sockindex), (uint8_t)(mtu & 0x00ff));
}

/********************************************************************************
 * Function Name  : CH394Q_SetSn_TOS
 * Description    : Set socket IP service type
 * Input          : sockindex: socket number
                    tos: type of service
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetSn_TOS(uint8_t sockindex, uint8_t tos)
{
    CH394Q_Write(Sn_TOS(sockindex), tos);
}

/********************************************************************************
 * Function Name  : CH394Q_SetSn_TTL
 * Description    : Set socket IP time to live
 * Input          : sockindex: socket number
                    ttl: Time to live
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetSn_TTL(uint8_t sockindex, uint8_t ttl)
{
    CH394Q_Write(Sn_TTL(sockindex), ttl);
}

/********************************************************************************
 * Function Name  : CH394Q_SetSn_RXBUF_SIZE
 * Description    : Set socket receive buffer size
 * Input          : sockindex: socket number
                    rxbuf: Receive buffer size
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetSn_RXBUF_SIZE(uint8_t sockindex, uint8_t rxbuf)
{
    CH394Q_Write(Sn_RXBUF_SIZE(sockindex), rxbuf);
}

/********************************************************************************
 * Function Name  : CH394Q_SetSn_TXBUF_SIZE
 * Description    : Set socket send buffer size
 * Input          : sockindex: socket number
                    txbuf: Send buffer size
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetSn_TXBUF_SIZE(uint8_t sockindex, uint8_t txbuf)
{
    CH394Q_Write(Sn_TXBUF_SIZE(sockindex), txbuf);
}

/********************************************************************************
 * Function Name  : CH394Q_SetSn_TX_WR
 * Description    : Set socket send write pointer
 * Input          : sockindex: socket number
                    txwr: Send data length
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetSn_TX_WR(uint8_t sockindex, uint16_t txwr)
{
    CH394Q_Write(Sn_TX_WR0(sockindex), (uint8_t)((txwr & 0xff00) >> 8));
    CH394Q_Write(Sn_TX_WR1(sockindex), (uint8_t)(txwr & 0x00ff));
}

/********************************************************************************
 * Function Name  : CH394Q_SetSn_RX_RD
 * Description    : Set socket receive read pointer
 * Input          : sockindex: socket number
                    rxrd: Receive data length
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetSn_RX_RD(uint8_t sockindex, uint16_t rxrd)
{
    CH394Q_Write(Sn_RX_RD0(sockindex), (uint8_t)((rxrd & 0xff00) >> 8));
    CH394Q_Write(Sn_RX_RD1(sockindex), (uint8_t)(rxrd & 0x00ff));
}

/********************************************************************************
 * Function Name  : CH394Q_SetSn_INTE
 * Description    : Enable socket interrupt
 * Input          : sockindex: socket number
                    inte: Enable socket interrupt
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetSn_INTE(uint8_t sockindex, uint8_t inte)
{
    CH394Q_Write(Sn_INTE(sockindex), inte);
}

/********************************************************************************
 * Function Name  : CH394Q_SetSn_IPF
 * Description    : Set socket IP header fragmentation
 * Input          : sockindex: socket number
                    ipf: IP fragmentation
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetSn_IPF(uint8_t sockindex, uint16_t ipf)
{
    CH394Q_Write(Sn_IPF0(sockindex), (uint8_t)((ipf & 0xff00) >> 8));
    CH394Q_Write(Sn_IPF1(sockindex), (uint8_t)(ipf & 0x00ff));
}

/********************************************************************************
 * Function Name  : CH394Q_SetSn_KEEPALIVE
 * Description    : Set keep a live interval
 * Input          : sockindex: socket number
                    val: Time interval (unit time is 5s)
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SetSn_KEEPALIVE(uint8_t sockindex, uint8_t val)
{
    CH394Q_Write(Sn_KEEPALIVE(sockindex), val);
}

/********************************************************************************
 * Function Name  : CH394Q_GetMODE
 * Description    : Get mode
 * Input          : None
 * Output         : None
 * Return         : Mode
 *******************************************************************************/
uint8_t CH394Q_GetMODE(void)
{
    return CH394Q_Read(MODE);
}

/********************************************************************************
 * Function Name  : CH394Q_GetGWIP
 * Description    : Get CH394Q gateway address
 * Input          : gwip: Gateway address pointer
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_GetGWIP(uint8_t *gwip)
{
    gwip[0] = CH394Q_Read(GWIP0);
    gwip[1] = CH394Q_Read(GWIP1);
    gwip[2] = CH394Q_Read(GWIP2);
    gwip[3] = CH394Q_Read(GWIP3);
}

/********************************************************************************
 * Function Name  : CH394Q_GetSMIP
 * Description    : Get CH394Q subnet mask address
 * Input          : smip: Subnet mask address pointer
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_GetSMIP(uint8_t *smip)
{
    smip[0] = CH394Q_Read(SMIP0);
    smip[1] = CH394Q_Read(SMIP1);
    smip[2] = CH394Q_Read(SMIP2);
    smip[3] = CH394Q_Read(SMIP3);
}

/********************************************************************************
 * Function Name  : CH394Q_GetMAC
 * Description    : Get CH394Q MAC address
 * Input          : mac: MAC address pointer
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_GetMAC(uint8_t *mac)
{
    mac[0] = CH394Q_Read(MAC0);
    mac[1] = CH394Q_Read(MAC1);
    mac[2] = CH394Q_Read(MAC2);
    mac[3] = CH394Q_Read(MAC3);
    mac[4] = CH394Q_Read(MAC4);
    mac[5] = CH394Q_Read(MAC5);
}

/********************************************************************************
 * Function Name  : CH394Q_GetIP
 * Description    : Get CH394Q source IP address
 * Input          : ip: Source IP address pointer
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_GetIP(uint8_t *ip)
{
    ip[0] = CH394Q_Read(IP0);
    ip[1] = CH394Q_Read(IP1);
    ip[2] = CH394Q_Read(IP2);
    ip[3] = CH394Q_Read(IP3);
}

/********************************************************************************
 * Function Name  : CH394Q_GetIIT
 * Description    : Get interrupt interval time
 * Input          : None
 * Output         : None
 * Return         : Interval time
 *******************************************************************************/
uint16_t CH394Q_GetIIT(void)
{
    uint16_t i = 0;
    i |= (CH394Q_Read(IIT0) << 8) & 0xff00;
    i |= CH394Q_Read(IIT1) & 0x00ff;
    return i;
}

/********************************************************************************
 * Function Name  : CH394Q_GetGINT
 * Description    : Get global interrupt status
 * Input          : None
 * Output         : None
 * Return         : Global Interrupt Status
 *******************************************************************************/
uint8_t CH394Q_GetGINT(void)
{
    return CH394Q_Read(GINT);
}

/********************************************************************************
 * Function Name  : CH394Q_GetGINTE
 * Description    : Get interrupt enable status
 * Input          : None
 * Output         : None
 * Return         : Enable interrupt status
 *******************************************************************************/
uint8_t CH394Q_GetGINTE(void)
{
    return CH394Q_Read(GINTE);
}

/********************************************************************************
 * Function Name  : CH394Q_GetSINT
 * Description    : Get socket interrupt status
 * Input          : None
 * Output         : None
 * Return         : Socket interrupt status
 *******************************************************************************/
uint8_t CH394Q_GetSINT(void)
{
    return CH394Q_Read(SINT);
}

/********************************************************************************
 * Function Name  : CH394Q_GetSINTE
 * Description    : Get enable socket interrupt status
 * Input          : None
 * Output         : None
 * Return         : Enable socket interrupt status
 *******************************************************************************/
uint8_t CH394Q_GetSINTE(void)
{
    return CH394Q_Read(SINTE);
}

/********************************************************************************
 * Function Name  : CH394Q_GetRTIME
 * Description    : Get retransmission timeout duration (unit time is 100us)
 * Input          : None
 * Output         : None
 * Return         : Retransmission timeout time
 *******************************************************************************/
uint16_t CH394Q_GetRTIME(void)
{
    uint16_t i = 0;
    i = (CH394Q_Read(RTIME0) << 8) & 0xff00;
    i |= CH394Q_Read(RTIME1) & 0x00ff;
    return i;
}

/********************************************************************************
 * Function Name  : CH394Q_GetRCNT
 * Description    : Get retransmission count
 * Input          : None
 * Output         : None
 * Return         : Retransmission count
 *******************************************************************************/
uint8_t CH394Q_GetRCNT(void)
{
    return CH394Q_Read(RCNT);
}

/********************************************************************************
 * Function Name  : CH394Q_GetUNIP
 * Description    : Get unable to reach IP address
 * Input          : unip: Unable to reach IP address pointer
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_GetUNIP(uint8_t *unip)
{
    unip[0] = CH394Q_Read(UNIP0);
    unip[1] = CH394Q_Read(UNIP1);
    unip[2] = CH394Q_Read(UNIP2);
    unip[3] = CH394Q_Read(UNIP3);
}

/********************************************************************************
 * Function Name  : CH394Q_GetUNPORT
 * Description    : Get unreachable port
 * Input          : None
 * Output         : None
 * Return         : Unreachable port
 *******************************************************************************/
uint16_t CH394Q_GetUNPORT(void)
{
    uint16_t i = 0;
    i |= (CH394Q_Read(UNPORT0) << 8) & 0xff00;
    i |= CH394Q_Read(UNPORT1) & 0x00ff;
    return i;
}

/********************************************************************************
 * Function Name  : CH394Q_GetPHYStatus
 * Description    : Get PHY status
 * Input          : None
 * Output         : None
 * Return         : PHY status
 *******************************************************************************/
uint8_t CH394Q_GetPHYStatus(void)
{
    return CH394Q_Read(PHY_CFG);
}

/********************************************************************************
 * Function Name  : CH394Q_GetCHIPV
 * Description    : Get CH394Q version number
 * Input          : None
 * Output         : None
 * Return         : Version number
 *******************************************************************************/
uint8_t CH394Q_GetCHIPV(void)
{
    return CH394Q_Read(CHIPV);
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_MODE
 * Description    : Get socket mode
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket mode
 *******************************************************************************/
uint8_t CH394Q_GetSn_MODE(uint8_t sockindex)
{
    return CH394Q_Read(Sn_MODE(sockindex));
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_CTRL
 * Description    : Get socket control command status
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket control command status
 *******************************************************************************/
uint8_t CH394Q_GetSn_CTRL(uint8_t sockindex)
{
    return CH394Q_Read(Sn_CTRL(sockindex));
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_INT
 * Description    : Get interrupt status of socket n
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : The interrupt state of socket n
 *******************************************************************************/
uint8_t CH394Q_GetSn_INT(uint8_t sockindex)
{
    return CH394Q_Read(Sn_INT(sockindex));
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_STA
 * Description    : Get socket status
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket status
 *******************************************************************************/
uint8_t CH394Q_GetSn_STA(uint8_t sockindex)
{
    return CH394Q_Read(Sn_STA(sockindex));
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_PORT
 * Description    : Get socket source port
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket source port
 *******************************************************************************/
uint16_t CH394Q_GetSn_PORT(uint8_t sockindex)
{
    uint16_t i = 0;
    i |= (CH394Q_Read(Sn_PORT0(sockindex)) << 8) & 0xff00;
    i |= CH394Q_Read(Sn_PORT1(sockindex)) & 0x00ff;
    return i;
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_DMAC
 * Description    : Get socket destination MAC address
 * Input          : sockindex: socket number
                    dmac: destination MAC address
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_GetSn_DMAC(uint8_t sockindex, uint8_t *dmac)
{
    dmac[0] = CH394Q_Read(Sn_DMAC0(sockindex));
    dmac[1] = CH394Q_Read(Sn_DMAC1(sockindex));
    dmac[2] = CH394Q_Read(Sn_DMAC2(sockindex));
    dmac[3] = CH394Q_Read(Sn_DMAC3(sockindex));
    dmac[4] = CH394Q_Read(Sn_DMAC4(sockindex));
    dmac[5] = CH394Q_Read(Sn_DMAC5(sockindex));
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_DIP
 * Description    : Get socket destination IP
 * Input          : sockindex: socket number
                    dip: socket destination IP
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_GetSn_DIP(uint8_t sockindex, uint8_t *dip)
{
    dip[0] = CH394Q_Read(Sn_DIP0(sockindex));
    dip[1] = CH394Q_Read(Sn_DIP1(sockindex));
    dip[2] = CH394Q_Read(Sn_DIP2(sockindex));
    dip[3] = CH394Q_Read(Sn_DIP3(sockindex));
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_DPORT
 * Description    : Get socket destination port
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket destination port
 *******************************************************************************/
uint16_t CH394Q_GetSn_DPORT(uint8_t sockindex)
{
    uint16_t i = 0;
    i |= (CH394Q_Read(Sn_DPORT0(sockindex)) << 8) & 0xff00;
    i |= CH394Q_Read(Sn_DPORT1(sockindex)) & 0x00ff;
    return i;
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_MTU
 * Description    : Get socket maximum segment
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket maximum segment
 *******************************************************************************/
uint16_t CH394Q_GetSn_MTU(uint8_t sockindex)
{
    uint16_t i = 0;
    i |= (CH394Q_Read(Sn_MTU0(sockindex)) << 8) & 0xff00;
    i |= CH394Q_Read(Sn_MTU1(sockindex)) & 0x00ff;
    return i;
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_TOS
 * Description    : Get socket service type
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket service type
 *******************************************************************************/
uint8_t CH394Q_GetSn_TOS(uint8_t sockindex)
{
    return CH394Q_Read(Sn_TOS(sockindex));
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_TTL
 * Description    : Get the socket IP time to live
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket IP time to live
 *******************************************************************************/
uint8_t CH394Q_GetSn_TTL(uint8_t sockindex)
{
    return CH394Q_Read(Sn_TTL(sockindex));
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_RXBUF_SIZE
 * Description    : Get socket receive buffer size
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket receive buffer size
 *******************************************************************************/
uint8_t CH394Q_GetSn_RXBUF_SIZE(uint8_t sockindex)
{
    return CH394Q_Read(Sn_RXBUF_SIZE(sockindex));
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_TXBUF_SIZE
 * Description    : Get socket send buffer size
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket send buffer size
 *******************************************************************************/
uint8_t CH394Q_GetSn_TXBUF_SIZE(uint8_t sockindex)
{
    return CH394Q_Read(Sn_TXBUF_SIZE(sockindex));
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_TX_FS
 * Description    : Get socket free send buffer size
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket free send buffer size
 *******************************************************************************/
uint16_t CH394Q_GetSn_TX_FS(uint8_t sockindex)
{
    uint16_t i = 0, t = 0;
    do
    {
        t = (CH394Q_Read(Sn_TX_FS0(sockindex)) << 8) & 0xff00;
        t |= CH394Q_Read(Sn_TX_FS1(sockindex)) & 0x00ff;
        if (t != 0)
        {
            i = (CH394Q_Read(Sn_TX_FS0(sockindex)) << 8) & 0xff00;
            i |= CH394Q_Read(Sn_TX_FS1(sockindex)) & 0x00ff;
        }
    } while (i != t);
    return i;
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_RX_RS
 * Description    : Get socket free receive buffer size
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket free receive buffer size
 *******************************************************************************/
uint16_t CH394Q_GetSn_RX_RS(uint8_t sockindex)
{
    uint16_t i = 0, t = 0;
    do
    {
        t = (CH394Q_Read(Sn_RX_RS0(sockindex)) << 8) & 0xff00;
        t |= CH394Q_Read(Sn_RX_RS1(sockindex)) & 0x00ff;
        if (t != 0)
        {
            i = (CH394Q_Read(Sn_RX_RS0(sockindex)) << 8) & 0xff00;
            i |= CH394Q_Read(Sn_RX_RS1(sockindex)) & 0x00ff;
        }
    } while (i != t);
    return i;
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_TX_RD
 * Description    : Get socket send read pointer
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket send read pointer
 *******************************************************************************/
uint16_t CH394Q_GetSn_TX_RD(uint8_t sockindex)
{
    uint16_t i = 0;
    i |= (CH394Q_Read(Sn_TX_RD0(sockindex)) << 8) & 0xff00;
    i |= CH394Q_Read(Sn_TX_RD1(sockindex)) & 0x00ff;
    return i;
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_TX_WR
 * Description    : Get socket send write pointer
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket send write pointer
 *******************************************************************************/
uint16_t CH394Q_GetSn_TX_WR(uint8_t sockindex)
{
    uint16_t i = 0;
    i |= (CH394Q_Read(Sn_TX_WR0(sockindex)) << 8) & 0xff00;
    i |= CH394Q_Read(Sn_TX_WR1(sockindex)) & 0x00ff;
    return i;
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_RX_RD
 * Description    : Get socket receive read pointer
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket receive read pointer
 *******************************************************************************/
uint16_t CH394Q_GetSn_RX_RD(uint8_t sockindex)
{
    uint16_t i = 0;
    i |= (CH394Q_Read(Sn_RX_RD0(sockindex)) << 8) & 0xff00;
    i |= CH394Q_Read(Sn_RX_RD1(sockindex)) & 0x00ff;
    return i;
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_RX_WR
 * Description    : Get socket receive write pointer
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket receive write pointer
 *******************************************************************************/
uint16_t CH394Q_GetSn_RX_WR(uint8_t sockindex)
{
    uint16_t i = 0;
    i |= (CH394Q_Read(Sn_RX_WR0(sockindex)) << 8) & 0xff00;
    i |= CH394Q_Read(Sn_RX_WR1(sockindex)) & 0x00ff;
    return i;
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_INTE
 * Description    : Get socket n enable interrupt status
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket n enable interrupt status
 *******************************************************************************/
uint8_t CH394Q_GetSn_INTE(uint8_t sockindex)
{
    return CH394Q_Read(Sn_INTE(sockindex));
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_IPF
 * Description    : Get socket segment status
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket segment status
 *******************************************************************************/
uint16_t CH394Q_GetSn_IPF(uint8_t sockindex)
{
    uint16_t i = 0;
    i |= (CH394Q_Read(Sn_IPF0(sockindex)) << 8) & 0xff00;
    i |= CH394Q_Read(Sn_IPF1(sockindex)) & 0x00ff;
    return i;
}

/********************************************************************************
 * Function Name  : CH394Q_GetSn_KEEPALIVE
 * Description    : Get socket keep a live transmission time (unit time is 5s)
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket keep a live transmission time
 *******************************************************************************/
uint8_t CH394Q_GetSn_KEEPALIVE(uint8_t sockindex)
{
    return CH394Q_Read(Sn_KEEPALIVE(sockindex));
}

/********************************************************************************
 * Function Name  : CH394Q_SocketSendData
 * Description    : socket send data
 * Input          : sockindex: socket number
                    buf: Send data buffer
                    len: Data length
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SocketSendData(uint8_t sockindex, uint8_t *buf, uint16_t len)
{
    uint16_t i = 0;
    uint32_t address = 0;
    i = CH394Q_GetSn_TX_WR(sockindex);
    address = (uint32_t)(i << 8) + (sockindex << 5) + 0x10;
    CH394Q_WriteBuf(address, buf, len);
    i += len;
    CH394Q_SetSn_TX_WR(sockindex, i);
}

/********************************************************************************
 * Function Name  : CH394Q_SocketRecvData
 * Description    : socket receive data
 * Input          : sockindex: socket number
                    buf: Receive data buffer
                    len: Data length
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SocketRecvData(uint8_t sockindex, uint8_t *buf, uint16_t len)
{
    uint16_t i = 0;
    uint32_t address = 0;
    while (CH394Q_GetSn_CTRL(sockindex));
    i = CH394Q_GetSn_RX_RD(sockindex);
    address = (uint32_t)(i << 8) + (sockindex << 5) + 0x18;
    CH394Q_ReadBuf(address, buf, len);
    i += len;
    CH394Q_SetSn_RX_RD(sockindex, i);
    CH394Q_SetSn_CTRL(sockindex, Sn_CTRL_RECV);
}

/********************************************************************************
 * Function Name  : CH394Q_SocketTCPSend
 * Description    : Send data in TCP mode
 * Input          : sockindex: socket number
                    buf: Send data buffer
                    len: Data length
 * Output         : None
 * Return         : Send successful return data length, fail return 0
 *******************************************************************************/
uint16_t CH394Q_SocketTCPSend(uint8_t sockindex, const uint8_t *buf, uint16_t len)
{
    uint16_t i = 0;
    uint16_t ferrbuf = 0;
    uint8_t Sn_STA_state = CH394Q_GetSn_STA(sockindex);
    if (len > CH394Q_GetTxMax(sockindex))
    {
        i = CH394Q_GetTxMax(sockindex);
    }
    else i = len;
    while (ferrbuf < i)
    {
        ferrbuf = CH394Q_GetSn_TX_FS(sockindex);
        Sn_STA_state = CH394Q_GetSn_STA(sockindex);
        if ((Sn_STA_state != SOCK_TCP_ESTABLISHED) && (Sn_STA_state != SOCK_CLOSE_WAIT))
        {
            printf("err\r\n");
            return 0;
        }
    }
    while (CH394Q_GetSn_CTRL(sockindex));
    CH394Q_SocketSendData(sockindex, (uint8_t *)buf, i);
    CH394Q_SetSn_CTRL(sockindex, Sn_CTRL_SEND);
    return i;
}

/********************************************************************************
 * Function Name  : CH394Q_SocketTCPRecv
 * Description    : Receive data in TCP mode
 * Input          : sockindex: socket number
                    buf: Receive data buffer
                    len: Data length
 * Output         : None
 * Return         : Return data length
 *******************************************************************************/
uint16_t CH394Q_SocketTCPRecv(uint8_t sockindex, uint8_t *buf, uint16_t len)
{
    uint16_t i = 0;
    if (len > 0)
    {
        CH394Q_SocketRecvData(sockindex, buf, len);
        i = len;
    }
    return i;
}

/********************************************************************************
 * Function Name  : CH394Q_SocketUDPSendTo
 * Description    : Send data in UDP mode
 * Input          : sockindex: socket number
                    buf: Send data buffer
                    len: Data length
                    desip: destination IP address
                    desport: destination port
 * Output         : None
 * Return         : data length
 *******************************************************************************/
uint16_t CH394Q_SocketSendTo(uint8_t sockindex, const uint8_t *buf, uint16_t len, uint8_t *desip, uint16_t desport)
{
    uint16_t i = 0;
    if (len > CH394Q_GetTxMax(sockindex))
    {
        i = CH394Q_GetTxMax(sockindex);
    }
    else i = len;
    CH394Q_SetSn_DIP(sockindex, desip);
    CH394Q_SetSn_DPORT(sockindex, desport);
    while (CH394Q_GetSn_CTRL(sockindex));
    CH394Q_SocketSendData(sockindex, (uint8_t *)buf, i);
    CH394Q_SetSn_CTRL(sockindex, Sn_CTRL_SEND);
    return i;
}

/********************************************************************************
 * Function Name  : CH394Q_Socket_UDP_Recv
 * Description    : Receive data in UDP mode
 * Input          : sockindex: socket number
                    buf: Receive data buffer
                    len: Data length
                    desip: destination IP address
                    desport: destination port
 * Output         : None
 * Return         : data length
 *******************************************************************************/
uint16_t CH394Q_Socket_UDP_Recv(uint8_t sockindex, uint8_t *buf, uint16_t len, uint8_t *desip, uint16_t *desport)
{
    uint8_t msg[8];
    uint16_t data_len = 0;
    if (len > 0)
    {
        CH394Q_SocketRecvData(sockindex, msg, 0x08);
        desip[0] = msg[0];
        desip[1] = msg[1];
        desip[2] = msg[2];
        desip[3] = msg[3];
        *desport = msg[4];
        *desport = (*desport << 8) + msg[5];
        data_len = msg[6];
        data_len = (data_len << 8) + msg[7];
        CH394Q_SocketRecvData(sockindex, buf, data_len);
    }
    return data_len;
}

/********************************************************************************
 * Function Name  : CH394Q_Socket_MACRAW_Send
 * Description    : Send data in MACRAW mode
 * Input          : sockindex: socket number
                    buf: Send data buffer
                    len: Data length
 * Output         : None
 * Return         : data length
 *******************************************************************************/
uint16_t CH394Q_Socket_MACRAW_Send(uint8_t sockindex, const uint8_t *buf, uint16_t len)
{
    uint16_t i = 0;
    if (len > CH394Q_GetTxMax(sockindex))
    {
        i = CH394Q_GetTxMax(sockindex);
    }
    else i = len;
    while (CH394Q_GetSn_CTRL(sockindex));
    CH394Q_SocketSendData(sockindex, (uint8_t *)buf, i);
    CH394Q_SetSn_CTRL(sockindex, Sn_CTRL_SEND);
    return i;
}
/********************************************************************************
 * Function Name  : CH394Q_Socket_MACRAW_Recv
 * Description    : Receive data in MACRAW mode
 * Input          : sockindex: socket number
                    buf: Receive data buffer
                    len: Data length
 * Output         : None
 * Return         : Send successful return data length, fail return 0
 *******************************************************************************/
uint16_t CH394Q_Socket_MACRAW_Recv(uint8_t sockindex, uint8_t *buf, uint16_t len)
{
    uint8_t msg[2];
    uint16_t data_len = 0;
    uint8_t socket_mode = CH394Q_GetSn_MODE(sockindex);
    if (len > 0)
    {
        if (socket_mode & Sn_MODE_MACRAW)
        {
            CH394Q_SocketRecvData(sockindex, msg, 0x02);
            data_len = msg[0];
            data_len = (data_len << 8) + msg[1] - 2;
            if (data_len > 1514)
            {
                CH394Q_SocketRecvData(sockindex, buf, len - 2);
                printf(" The received data length is more than 1514\r\n");
                return 0;
            }
            CH394Q_SocketRecvData(sockindex, buf, data_len);
        }
    }
    return data_len;
}

/********************************************************************************
 * Function Name  : CH394Q_SocketSendMAC
 * Description    : Use the send_mac command to send data
 * Input          : sockindex: socket number
                    buf: Send data buffer
                    len: Data length
                    desmac: Destination MAC address
                    desip: Destination IP address
                    desport: Destination Port
 * Output         : None
 * Return         : Data length
 *******************************************************************************/
uint16_t CH394Q_SocketSendMAC(uint8_t sockindex, const uint8_t *buf, uint16_t len, uint8_t *desmac, uint8_t *desip, uint16_t desport)
{
    uint16_t i = 0;
    if (len > CH394Q_GetTxMax(sockindex))
    {
        i = CH394Q_GetTxMax(sockindex);
    }
    else i = len;
    CH394Q_SetSn_DMAC(sockindex, desmac);
    CH394Q_SetSn_DIP(sockindex, desip);
    CH394Q_SetSn_DPORT(sockindex, desport);
    while (CH394Q_GetSn_CTRL(sockindex));
    CH394Q_SocketSendData(sockindex, (uint8_t *)buf, i);
    CH394Q_SetSn_CTRL(sockindex, Sn_CTRL_SEND_MAC);
    return i;
}

/********************************************************************************
 * Function Name  : CH394Q_Socket_Init
 * Description    : CH394Q socket initialization
 * Input          : sockindex: socket number
                    mode: socket mode
                    port: Source Port
 * Output         : None
 * Return         : None
 *******************************************************************************/

void CH394Q_Socket_Init(uint8_t sockindex, uint8_t mode, uint16_t port)
{
    uint16_t t;
    CH394Q_Socket_Close(sockindex);
    CH394Q_SetSn_MODE(sockindex, mode);
    if (port != 0)
    {
        CH394Q_SetSn_PORT(sockindex, port);
    }
    else
    {
        t = 8000 + sockindex;
        CH394Q_SetSn_PORT(sockindex, t);
    }
    CH394Q_Socket_Open(sockindex);
}

/********************************************************************************
 * Function Name  : CH394Q_Socket_Open
 * Description    : Open socket
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_Socket_Open(uint8_t sockindex)
{
    CH394Q_SetSn_CTRL(sockindex, Sn_CTRL_OPEN);
    while (CH394Q_GetSn_CTRL(sockindex));
}

/********************************************************************************
 * Function Name  : CH394Q_Socket_Close
 * Description    : Close socket
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_Socket_Close(uint8_t sockindex)
{
    CH394Q_SetSn_CTRL(sockindex, Sn_CTRL_CLOSE);
    while (CH394Q_GetSn_CTRL(sockindex));
    CH394Q_SetSn_INT(sockindex, 0xFF);
}

/********************************************************************************
 * Function Name  : CH394Q_Socket_Listen
 * Description    : Open listening
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_Socket_Listen(uint8_t sockindex)
{
    if (CH394Q_GetSn_STA(sockindex) == SOCK_INIT)
    {
        CH394Q_SetSn_CTRL(sockindex, Sn_CTRL_LISTEN);
        while (CH394Q_GetSn_CTRL(sockindex));
    }
}

/********************************************************************************
 * Function Name  : CH394Q_Socket_Connect
 * Description    : Establish connection
 * Input          : sockindex: socket number
                    desip: Destination server address
                    desport: Destination server port
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_Socket_Connect(uint8_t sockindex, uint8_t *desip, uint16_t desport)
{
    CH394Q_SetSn_DIP(sockindex, desip);
    CH394Q_SetSn_DPORT(sockindex, desport);
    CH394Q_SetSn_CTRL(sockindex, Sn_CTRL_CONNECT);
    while (CH394Q_GetSn_CTRL(sockindex));
}

/********************************************************************************
 * Function Name  : CH394Q_Socket_Disconnect
 * Description    : socket disconnect
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_Socket_Disconnect(uint8_t sockindex)
{
    CH394Q_SetSn_CTRL(sockindex, Sn_CTRL_DISCONNECT);
    while (CH394Q_GetSn_CTRL(sockindex));
}

/********************************************************************************
 * Function Name  : CH394Q_SocketBuf_Init
 * Description    : Initialize socket receive and send buffer size
 * Input          : tx_size: Set send buffer size
                    rx_size: Set receive buffer size
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_SocketBuf_Init(uint8_t *tx_size, uint8_t *rx_size)
{
    uint16_t i;
    for (i = 0; i < SOCKET_NUM; i++)
    {
        CH394Q_SetSn_TXBUF_SIZE(i, tx_size[i]);
        CH394Q_SetSn_RXBUF_SIZE(i, rx_size[i]);
    }
    // HAL_Delay(1);
    usleep(10000);
}

/********************************************************************************
 * Function Name  : CH394Q_GetRxMax
 * Description    : Get socket n maximum receive buffer
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket n maximum receive buffer
 *******************************************************************************/
uint16_t CH394Q_GetRxMax(uint8_t sockindex)
{
    return RX_BUFF[sockindex] * 1024;
}

/********************************************************************************
 * Function Name  : CH394Q_GetTxMax
 * Description    : Get socket n maximum send buffer
 * Input          : sockindex: socket number
 * Output         : None
 * Return         : socket n max send buffer
 *******************************************************************************/
uint16_t CH394Q_GetTxMax(uint8_t sockindex)
{
    return TX_BUFF[sockindex] * 1024;
}

/********************************************************************************
 * Function Name  : CH394Q_InfParam
 * Description    : Configure CH394Q network parameters
 * Input          : ip: Source IP
                    smip: Source Mask
                    gwip: Source Gateway
                    mac: Source MAC
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_InfParam(uint8_t *ip, uint8_t *smip, uint8_t *gwip, uint8_t *mac)
{
    CH394Q_SetIP(ip);
    CH394Q_SetSMIP(smip);
    CH394Q_SetGWIP(gwip);
    CH394Q_GetMAC(mac);
    printf(" CH394Q MAC address : %02x.%02x.%02x.%02x.%02x.%02x\r\n", mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
    CH394Q_GetIP(ip);
    printf(" CH394Q IP address  : %d.%d.%d.%d\r\n", ip[0], ip[1], ip[2], ip[3]);
    CH394Q_GetSMIP(smip);
    printf(" CH394Q subnet mask : %d.%d.%d.%d\r\n", smip[0], smip[1], smip[2], smip[3]);
    CH394Q_GetGWIP(gwip);
    printf(" CH394Q gateway     : %d.%d.%d.%d\r\n", gwip[0], gwip[1], gwip[2], gwip[3]);
}

/********************************************************************************
 * Function Name  : CH394Q_PHY_Check
 * Description    : PHY connection check
 * Input          : None
 * Output         : None
 * Return         : None
 *******************************************************************************/
uint8_t CH394Q_PHY_Check(void)
{
    uint8_t PHY_state = 0;
    while (1)
    {
        static uint16_t phy_check_count = 0;
        PHY_state = CH394Q_GetPHYStatus();
        if (((PHY_state & 0x01) == 0 ) || (PHY_state == 0xff))
        {
            // HAL_Delay(500);
            usleep(500000);
            phy_check_count++;
            if(phy_check_count > 10)
            {
                print("Phy initalize fail!\r\n");
                return 1;//err
            }
        }
        else
        {
            printf(" Link up..\r\n");
            break;
        }
    }
    return 0;
}

/********************************************************************************
 * Function Name  : CH394Q_ResetSW
 * Description    : CH394Q software reset
 * Input          : None
 * Output         : None
 * Return         : None
 *******************************************************************************/
void CH394Q_ResetSW(void)
{
    CH394Q_SetMODE(MODE_RST);
    usleep(500000);
    // HAL_Delay(500);
}

/*******************************************************************************
 * Function Name  : CH394Q_ResetHW
 * Description    : CH394Q hardware reset
 * Input          : None
 * Return         : None
 *******************************************************************************/


void CH394Q_ResetHW(void)
{
    // GPIO_ResetBits(GPIOB, GPIO_Pin_5);
    // Delay_Ms(500);
    // GPIO_SetBits(GPIOB, GPIO_Pin_5);
    // Delay_Ms(500);
    // HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
    // HAL_Delay(500);
    // HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_RESET);
    // HAL_Delay(500);
    // HAL_GPIO_WritePin(GPIOB, GPIO_PIN_5, GPIO_PIN_SET);
    // HAL_Delay(500);
    uint32_t gpio_status = XGpio_DiscreteRead(&gpio, CH394Q_RESET_CHANNEL);
    XGpio_DiscreteWrite(&gpio, CH394Q_RESET_CHANNEL, gpio_status | CH394Q_RESET);//RESET HIGH
    usleep(500000);
    gpio_status = XGpio_DiscreteRead(&gpio, CH394Q_RESET_CHANNEL);
    XGpio_DiscreteWrite(&gpio, CH394Q_RESET_CHANNEL, gpio_status & (~CH394Q_RESET));////RESET LOW
    usleep(500000);
    gpio_status = XGpio_DiscreteRead(&gpio, CH394Q_RESET_CHANNEL);
    XGpio_DiscreteWrite(&gpio, CH394Q_RESET_CHANNEL, gpio_status | CH394Q_RESET);//RESET HIGH
    usleep(500000);
}





void ch394q_tcp_server_init(void)
{


    CH394Q_ResetHW(); // CH394Q hardware reset
    printf("\r\n CH394Q EVT Test Demo \r\n");
    uint16_t i = CH394Q_GetCHIPV();
    printf(" CH394Q CHIPV : %2x\r\n", i);
    if(1 == CH394Q_PHY_Check())
    {
        return;
    }                                                        // PHY Connection Check
    CH394Q_InfParam(CH394Q_IPAddr, CH394Q_IPMask, CH394Q_GWIPAddr, CH394Q_MACAddr); // Set CH394Q network parameters
    CH394Q_SocketBuf_Init(TX_BUFF, RX_BUFF);                                        // Initialize buffer size
    CH394Q_SetGINTE(0XFF);                                                          // Enable global interrupt
    CH394Q_SetSINTE(0XFF);                                                          // Enable socket interrupt
    printf(" TCP SERVER......\r\n");
    CH394Q_TCPServerSocketInit(0, Sn_MODE_TCP, CH394Q_Port);
}




